#!/bin/bash

# Original script by Walter Heitman Jr, first published on http://blog.shanock.com
#
# Permission is hereby given to use, modify, or redistribute this code in any form or
# fashion for any purpose, private or commercial, so long as the credit comment is left intact.

# Location of Fail2Ban sqlite database
DATABASE=/var/lib/fail2ban/fail2ban.sqlite3

# iprables prefix for Fail2ban chains. Default is "fail2ban"
JAILPREFIX="f2b"

# Get Jails. You can manually change this to a list of jails, as per the commented-out example
JAILS=$(fail2ban-client status | grep "Jail list" | cut -f2- | sed 's/,//g')
#JAILS="postfix-sasl sshd apache-auth"

# See if user wants to force the unban via direct iptables command (i.e. fail2ban lost its database)
FORCE=0
while getopts "f" OPTION; do
        case $OPTION in
                f)
                        FORCE=1
                        shift $(($OPTIND - 1))
                        ;;
        esac
done

# Loop through each jail
for JAIL in $JAILS; do
    # Ask iptables and loop through each IP in the jail
    for IPADDRESS in $(iptables -L $JAILPREFIX-$JAIL -n | grep -Eo '([0-9]{1,3}\.){3}[1-9]{1,3}' | grep -v '0.0.0.0'); do
        # Check for parameters, which should be individual IPs to unban
        if [ $1 ]; then
            # Loop through parameters
            for UNBANTHIS in "$@"; do
                # If match, unban it the "correct" way
                if [ $UNBANTHIS == $IPADDRESS ]; then
                    fail2ban-client set $JAIL unbanip $IPADDRESS
                    # If force, make sure IP is unbanned via direct command to iptables
                    if [ $FORCE == 1 ]; then
                        /sbin/iptables -D $JAILPREFIX-$JAIL -s $IPADDRESS -j REJECT
                    fi
                fi
            done
        else
            # If no parameters are specified, just unban everything we find
            fail2ban-client set $JAIL unbanip $IPADDRESS
        fi
    done
done

# Force clear from fail2ban database
if [ $1 ]; then
    # Loop through parameters, clear each IP from all jails
    for UNBANTHIS in "$@"; do
        echo -e ".timeout 10000\ndelete from bans where ip = '$UNBANTHIS';" | sqlite3 -echo $DATABASE 
    done
else
    # If no parameters are specified, just purge the entire database
    echo -e ".timeout 10000\ndelete from bans;" | sqlite3 -echo $DATABASE
        if [ $FORCE == 1 ]; then

        # If force, flush every iptables chain
        for JAIL in $JAILS; do
                /sbin/iptables -F $JAILPREFIX-$JAIL 
        done
        fi

fi
